#include "stdafx.h"
#include "Junctions.h"
#include "ShortReadUtil.h"

CJunction::CJunction(void)
{
}

CJunction::~CJunction(void)
{
}

CJunction::CJunction(char* line)
{
    vector<string> v;
    Tokenize(string(line), v, "\t ");
    this->start = atoi(v.at(1).c_str());
    this->end = atoi(v.at(2).c_str());
    this->support = atoi(v.at(4).c_str());
    this->strand = v.at(5).at(0);
}

CJunction::CJunction(int start, int end)
{
    this->start = min(start, end);
    this->end = max(start, end);
    this->strand = (start < end ) ? '+': '-';
    this->support = 0;
}

CJunctions::CJunctions(string geneName, bool forward)
{
    this->geneName = geneName;
    this->forward = forward;
}

CJunctions::~CJunctions(void)
{
}

int CJunctions::addJunction(CJunction junction)
{
    // junction.strand = (forward ? '+' : '-');
    if ((junction.strand == '+' && forward) ||
            (junction.strand == '-' && !forward)) {
        this->JunctionsV.push_back(junction);
    } // add the junction only if it is consistent with the selected direction.
    return(0);
}

int CJunctions::addJunctions(vector<pair <int, int> >& num_pair, bool forward)
{
    for (vector<pair <int, int> >::iterator i = num_pair.begin();
            i != num_pair.end(); i++) {
        CJunction j(i->first, i->second);
        j.strand = forward ? '+' : '-';
        j.support = 0;
        addJunction(j);
    }
    return(0);
}

void CJunctions::sortJunctions(bool forward)
{
    if (forward) {
        return(std::sort(this->JunctionsV.begin(), this->JunctionsV.end(), CForwardComp()));
    } else {
        return(std::sort(this->JunctionsV.begin(), this->JunctionsV.end(), CBackwardComp()));
    }

}

vector<CJunction>::iterator CJunctions::nextJunction(int start, int end)
{
    CJunction j(start, end);
    if (forward) {
        return(upper_bound(this->JunctionsV.begin(), this->JunctionsV.end(), j, CForwardComp()));
    } else {
        return(upper_bound(this->JunctionsV.begin(), this->JunctionsV.end(), j, CBackwardComp()));
    }
}
// TODO sort the junction after add
const int SPLICE_PAT_NO = 3;
int checkJunctionSeq(const char* juncSeq)
{
    const char* splicePat[SPLICE_PAT_NO] = {"gtag", "gcag", "gcag"};
    // List donor-acceptor patterns
    int i;
    for (i = 0; i < SPLICE_PAT_NO ; i++) {
        if (strncmp(juncSeq, splicePat[i], 4) == 0) {
            return(i);
        }
    }
    return(i);
}

int checkJunctionStrand(const char* seq, CJunction& j)
{
    char juncSeq[FILENAME_MAX];
    if (j.start >= 0 && j.end < (int)strlen(seq)) {
        juncSeq[0] = tolower(seq[j.start ]);
        juncSeq[1] = tolower(seq[j.start + 1]);
        juncSeq[2] = tolower(seq[j.end -2 ]);
        juncSeq[3] = tolower(seq[j.end - 1]);
        juncSeq[4] = '\0';

        if (checkJunctionSeq(juncSeq) < SPLICE_PAT_NO) {
            return(0);
        }
        reverseComplementKmer(juncSeq);
        if (checkJunctionSeq(juncSeq) < SPLICE_PAT_NO) {
            return(1);
        }
    }
    return(-1); // error junction
}
